package com.warning_speed_android.worker;

import android.util.Log;

public abstract class BaseWorker {
	public static final int DEFAULT_INTERVAL = 5000;

	private Object _syncObject;
	private Thread _thread;
	private long _delayInterval;
	private boolean _isWorking;
	protected String _name;

	public BaseWorker() {
		_syncObject = new Object();
		_delayInterval = DEFAULT_INTERVAL;
		_isWorking = false;
		_name = BaseWorker.class.getName();
	}

	public BaseWorker(String name) {
		this();
		_name = name;
	}

	public final boolean startWorker() {
		boolean success = false;
		try {
			if (_thread == null || _thread.isInterrupted()) {
				_thread = new Thread(new Runnable() {
					@Override
					public void run() {
						Log.i(BaseWorker.class.getSimpleName(), _name + " is running");
						_isWorking = true;
						while (_isWorking) {
							try {
								onProcess();
								synchronized (getSyncObject()) {
									if (_delayInterval > 0) {
										getSyncObject().wait(_delayInterval);
									}
								}
							} catch (InterruptedException ex) {
								Log.e(BaseWorker.class.getSimpleName(), "onRun()", ex);
							}
						}
						Log.i(BaseWorker.class.getSimpleName(), _name + " is stoped.");
					}
				});
				_thread.setName(_name);
			}
			if (!_thread.isAlive()) {
				_thread.start();
			}
			success = true;
		} catch (Exception ex) {
			Log.e(BaseWorker.class.getSimpleName(), "Can't start thread", ex);
		}
		return success;
	}

	public final void stopWorker() {
		try {
			_isWorking = false;
			synchronized (_syncObject) {
				_syncObject.notify();
			}
		} catch (Exception ex) {
			Log.e(BaseWorker.class.getSimpleName(), "An error occur when stop worker", ex);
		}
	}

	protected abstract void onProcess();

	/**
	 * @return the _delayInterval
	 */
	public long getInterval() {
		return _delayInterval;
	}

	/**
	 * @param interval
	 *            the _delayInterval to set
	 */
	public void setInterval(long interval) {
		this._delayInterval = interval;
	}

	/**
	 * @return the _isWorking
	 */
	public boolean isWorking() {
		return _isWorking;
	}

	/**
	 * @return the _syncObject
	 */
	public final Object getSyncObject() {
		return _syncObject;
	}
}
